home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util4 / bytmrk20.lha / sysspec.c < prev    next >
C/C++ Source or Header  |  1995-11-03  |  14KB  |  644 lines

  1.  
  2. /*
  3. ** sysspec.c
  4. ** BYTEmark (tm)
  5. ** BYTE's Native Mode Benchmarks
  6. ** Rick Grehan, BYTE Magazine
  7. */
  8.  
  9. /***********************************
  10. **    SYSTEM-SPECIFIC ROUTINES    **
  11. ************************************
  12. **
  13. ** These are the routines that provide functions that are
  14. ** system-specific.  If the benchmarks are to be ported
  15. ** to new hardware/new O.S., this is the first place to
  16. ** start.
  17. */
  18. #include "sysspec.h"
  19.  
  20. #ifdef DOS16
  21. #include <io.h>
  22. #include <fcntl.h>
  23. #include <sys\stat.h>
  24. #endif
  25. /*********************************
  26. **  MEMORY MANAGEMENT ROUTINES  **
  27. *********************************/
  28.  
  29.  
  30. /****************************
  31. ** AllocateMemory
  32. ** This routine returns a void pointer to a memory
  33. ** block.  The size of the memory block is given in bytes
  34. ** as the first argument.  This routine also returns an
  35. ** error code in the second argument.
  36. ** NOTE: For systems that return relocatable blocks (Windows and
  37. ** the Mac, for example) this routine will have to resolve the
  38. ** handle to an address and lock that handle.  The FreeMemory
  39. ** routine in such systems will need a way to resolve the
  40. ** address back into its handle in order to free the memory.
  41. ** One sneaky way to do this would be to allocate enough
  42. ** memory PLUS 1 longword.  Lock the memory, stick the handle
  43. ** in the first longword, and return an address that is the
  44. ** original address + 4 bytes.  In that way, the FreeMemory
  45. ** routine can retrieve the original handle.
  46. */
  47. farvoid *AllocateMemory(unsigned long nbytes,   /* # of bytes to alloc */
  48.                 int *errorcode)                 /* Returned error code */
  49. {
  50. #ifdef DOS16MEM
  51. union REGS registers;
  52. unsigned int nparas;            /* # of paragraphs */
  53.  
  54. /*
  55. ** Set # of paragraphs to nbytes/16 +1.  The +1 is a
  56. ** slop factor.
  57. */
  58. nparas=(unsigned int)(nbytes>>4) + 1;
  59.  
  60. /*
  61. ** Set incoming registers.
  62. */
  63. registers.h.ah=0x48;            /* Allocate memory */
  64. registers.x.bx=nparas;          /* # of paragraphs */
  65.  
  66. intdos(®isters,®isters);  /* Call DOS */
  67.  
  68. /*
  69. ** See if things succeeded.
  70. */
  71. if(registers.x.cflag)
  72. {       *errorcode=ERROR_MEMORY;
  73.         return((farvoid *)NULL);
  74. }
  75.  
  76. /*
  77. ** Create a farvoid pointer to return.
  78. */
  79. *errorcode=0;
  80. return((farvoid *)MK_FP(registers.x.ax,0));
  81.  
  82. #endif
  83.  
  84. #ifdef MACMEM
  85. /*
  86. ** For MAC CodeWarrior, we'll use the MacOS NewPtr call
  87. */
  88. farvoid *returnval;
  89. returnval=(farvoid *)NewPtr((Size)nbytes);
  90. if(returnval==(farvoid *)NULL)
  91.         *errorcode=ERROR_MEMORY;
  92. else
  93.         *errorcode=0;
  94. return(returnval);
  95. #endif
  96.  
  97. #ifdef MALLOCMEM
  98. /*
  99. ** Everyone else, its pretty straightforward, given
  100. ** that you use a 32-bit compiler which treats size_t as
  101. ** a 4-byte entity.
  102. */
  103. farvoid *returnval;             /* Return value */
  104.  
  105. returnval=(farvoid *)malloc((size_t)nbytes);
  106. if(returnval==(farvoid *)NULL)
  107.         *errorcode=ERROR_MEMORY;
  108. else
  109.         *errorcode=0;
  110. return(returnval);
  111. #endif
  112.  
  113. }
  114.  
  115.  
  116. /****************************
  117. ** FreeMemory
  118. ** This is the reverse of AllocateMemory.  The memory
  119. ** block passed in is freed.  Should an error occur,
  120. ** that error is returned in errorcode.
  121. */
  122. void FreeMemory(farvoid *mempointer,    /* Pointer to memory block */
  123.                 int *errorcode)
  124. {
  125. #ifdef DOS16MEM
  126. /*
  127. ** 16-bit DOS VERSION!!
  128. */
  129. unsigned int segment;
  130. unsigned int offset;
  131. union REGS registers;
  132. struct SREGS sregisters;
  133.  
  134. /*
  135. ** First get the segment/offset of the farvoid pointer.
  136. */
  137. segment=FP_SEG(mempointer);
  138. offset=FP_OFF(mempointer);
  139.  
  140. /*
  141. ** Align the segment properly.  For as long as offset > 16,
  142. ** subtract 16 from offset and add 1 to segment.
  143. */
  144. while(offset>=16)
  145. {       offset-=16;
  146.         segment++;
  147. }
  148.  
  149. /*
  150. ** Build the call to DOS
  151. */
  152. registers.h.ah=0x49;            /* Free memory */
  153. sregisters.es=segment;
  154.  
  155. intdosx(®isters,®isters,&sregisters);
  156.  
  157. /*
  158. ** Check for error
  159. */
  160. if(registers.x.cflag)
  161. {       *errorcode=ERROR_MEMORY;
  162.         return;
  163. }
  164.  
  165. *errorcode=0;
  166. return;
  167. #endif
  168.  
  169. #ifdef MACMEM
  170. DisposPtr((Ptr)mempointer);
  171. *errorcode=0;
  172. return;
  173. #endif
  174.  
  175. #ifdef MALLOCMEM
  176.  
  177. free(mempointer);
  178. *errorcode=0;
  179. return;
  180. #endif
  181. }
  182.  
  183. /****************************
  184. ** MoveMemory
  185. ** Moves n bytes from a to b.  Handles overlap.
  186. ** In most cases, this is just a memmove operation.
  187. ** But, not in DOS....noooo....
  188. */
  189. void MoveMemory( farvoid *destination,  /* Destination address */
  190.                 farvoid *source,        /* Source address */
  191.                 unsigned long nbytes)
  192. {
  193.  
  194. /* +++16-bit DOS VERSION+++ */
  195. #ifdef DOS16MEM
  196.  
  197.         FarDOSmemmove( destination, source, nbytes);
  198.  
  199. #else
  200.  
  201. memmove(destination, source, nbytes);
  202.  
  203. #endif
  204. }
  205.  
  206. #ifdef DOS16MEM
  207.  
  208. /****************************
  209. ** FarDOSmemmove
  210. ** Performs the same function as memmove for DOS when
  211. ** the arrays are defined with far pointers.
  212. */
  213. void FarDOSmemmove(farvoid *destination,        /* Destination pointer */
  214.                 farvoid *source,        /* Source pointer */
  215.                 unsigned long nbytes)   /* # of bytes to move */
  216. {
  217. unsigned char huge *uchsource;  /* Temp source */
  218. unsigned char huge *uchdest;    /* Temp destination */
  219. unsigned long saddr;            /* Source "true" address */
  220. unsigned long daddr;            /* Destination "true" address */
  221.  
  222.  
  223. /*
  224. ** Get unsigned char pointer equivalents
  225. */
  226. uchsource=(unsigned char huge *)source;
  227. uchdest=(unsigned char huge *)destination;
  228.  
  229. /*
  230. ** Calculate true address of source and destination and
  231. ** compare.
  232. */
  233. saddr=(unsigned long)(FP_SEG(source)*16 + FP_OFF(source));
  234. daddr=(unsigned long)(FP_SEG(destination)*16 + FP_OFF(destination));
  235.  
  236. if(saddr > daddr)
  237. {
  238.         /*
  239.         ** Source is greater than destination.
  240.         ** Use a series of standard move operations.
  241.         ** We'll move 65535 bytes at a time.
  242.         */
  243.         while(nbytes>=65535L)
  244.         {       _fmemmove((farvoid *)uchdest,
  245.                         (farvoid *)uchsource,
  246.                         (size_t) 65535);
  247.                 uchsource+=65535;       /* Advance pointers */
  248.                 uchdest+=65535;
  249.                 nbytes-=65535;
  250.         }
  251.  
  252.         /*
  253.         ** Move remaining bytes
  254.         */
  255.         if(nbytes!=0L)
  256.                 _fmemmove((farvoid *)uchdest,
  257.                         (farvoid *)uchsource,
  258.                         (size_t)(nbytes & 0xFFFF));
  259.  
  260. }
  261. else
  262. {
  263.         /*
  264.         ** Destination is greater than source.
  265.         ** Advance pointers to the end of their
  266.         ** respective blocks.
  267.         */
  268.         uchsource+=nbytes;
  269.         uchdest+=nbytes;
  270.  
  271.         /*
  272.         ** Again, move 65535 bytes at a time.  However,
  273.         ** "back" the pointers up before doing the
  274.         ** move.
  275.         */
  276.         while(nbytes>=65535L)
  277.         {
  278.                 uchsource-=65535;
  279.                 uchdest-=65535;
  280.                 _fmemmove((farvoid *)uchdest,
  281.                         (farvoid *)uchsource,
  282.                         (size_t) 65535);
  283.                 nbytes-=65535;
  284.         }
  285.  
  286.         /*
  287.         ** Move remaining bytes.
  288.         */
  289.         if(nbytes!=0L)
  290.         {       uchsource-=nbytes;
  291.                 uchdest-=nbytes;
  292.                 _fmemmove((farvoid *)uchdest,
  293.                         (farvoid *)uchsource,
  294.                         (size_t)(nbytes & 0xFFFF));
  295.         }
  296. }
  297. return;
  298. }
  299. #endif
  300.  
  301. /**********************************
  302. **    FILE HANDLING ROUTINES     **
  303. **********************************/
  304.  
  305. /****************************
  306. ** CreateFile
  307. ** This routine accepts a filename for an argument and
  308. ** creates that file in the current directory (unless the
  309. ** name contains a path that overrides the current directory).
  310. ** Note that the routine does not OPEN the file.
  311. ** If the file exists, it is truncated to length 0.
  312. */
  313. void CreateFile(char *filename,
  314.                 int *errorcode)
  315. {
  316.  
  317. #ifdef DOS16
  318. /*
  319. ** DOS VERSION!!
  320. */
  321. int fhandle;            /* File handle used internally */
  322.  
  323. fhandle=open(filename,O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  324.  
  325. if(fhandle==-1)
  326.         *errorcode=ERROR_FILECREATE;
  327. else
  328.         *errorcode=0;
  329.  
  330. /*
  331. ** Since all we're doing here is creating the file,
  332. ** go ahead and close it.
  333. */
  334. close(fhandle);
  335.  
  336. return;
  337. #endif
  338. }
  339.  
  340. /****************************
  341. ** bmOpenFile
  342. ** Opens the file given by fname, returning its handle.
  343. ** If an error occurs, returns its code in errorcode.
  344. ** The file is opened in read-write exclusive mode.
  345. */
  346. int bmOpenFile(char *fname,       /* File name */
  347.         int *errorcode)         /* Error code returned */
  348. {
  349.  
  350. #ifdef DOS16
  351. /*
  352. ** DOS VERSION!!
  353. */
  354. int fhandle;            /* Returned file handle */
  355.  
  356. fhandle=open(fname,O_BINARY | O_RDWR, S_IREAD | S_IWRITE);
  357.  
  358. if(fhandle==-1)
  359.         *errorcode=ERROR_FILEOPEN;
  360. else
  361.         *errorcode=0;
  362.  
  363. return(fhandle);
  364. #endif
  365.  
  366. }
  367.  
  368. /****************************
  369. ** CloseFile
  370. ** Closes the file identified by fhandle.
  371. ** A more inocuous routine there never was.
  372. */
  373. void CloseFile(int fhandle,             /* File handle */
  374.                 int *errorcode)         /* Returned error code */
  375. {
  376.  
  377. #ifdef DOS16
  378. /*
  379. ** DOS VERSION!!!
  380. */
  381. close(fhandle);
  382. *errorcode=0;
  383. return;
  384. #endif
  385.  
  386. }
  387.  
  388. /****************************
  389. ** readfile
  390. ** Read bytes from an opened file.  This routine
  391. ** is a combination seek-and-read.
  392. ** Note that this routine expects the offset to be from
  393. ** the beginning of the file.
  394. */
  395. void readfile(int fhandle,              /* File handle */
  396.         unsigned long offset,           /* Offset into file */
  397.         unsigned long nbytes,           /* # of bytes to read */
  398.         void *buffer,                   /* Buffer to read into */
  399.         int *errorcode)                 /* Returned error code */
  400. {
  401.  
  402. #ifdef DOS16
  403. /*
  404. ** DOS VERSION!!
  405. */
  406.  
  407. long newoffset;                         /* New offset by lseek */
  408. int readcode;                           /* Return code from read */
  409.  
  410. /*
  411. ** Presume success.
  412. */
  413. *errorcode=0;
  414.  
  415. /*
  416. ** Seek to the proper offset.
  417. */
  418. newoffset=lseek(fhandle,(long)offset,SEEK_SET);
  419. if(newoffset==-1L)
  420. {       *errorcode=ERROR_FILESEEK;
  421.         return;
  422. }
  423.  
  424. /*
  425. ** Do the read.
  426. */
  427. readcode=read(fhandle,buffer,(unsigned)(nbytes & 0xFFFF));
  428. if(readcode==-1)
  429.         *errorcode=ERROR_FILEREAD;
  430.  
  431. return;
  432. #endif
  433.  
  434. }
  435.  
  436. /****************************
  437. ** writefile
  438. ** writes bytes to an opened file.  This routine is
  439. ** a combination seek-and-write.
  440. ** Note that this routine expects the offset to be from
  441. ** the beinning of the file.
  442. */
  443. void writefile(int fhandle,             /* File handle */
  444.         unsigned long offset,           /* Offset into file */
  445.         unsigned long nbytes,           /* # of bytes to read */
  446.         void *buffer,                   /* Buffer to read into */
  447.         int *errorcode)                 /* Returned error code */
  448. {
  449.  
  450. #ifdef DOS16
  451. /*
  452. ** DOS VERSION!!
  453. */
  454.  
  455. long newoffset;                         /* New offset by lseek */
  456. int writecode;                          /* Return code from write */
  457.  
  458. /*
  459. ** Presume success.
  460. */
  461. *errorcode=0;
  462.  
  463. /*
  464. ** Seek to the proper offset.
  465. */
  466. newoffset=lseek(fhandle,(long)offset,SEEK_SET);
  467. if(newoffset==-1L)
  468. {       *errorcode=ERROR_FILESEEK;
  469.         return;
  470. }
  471.  
  472. /*
  473. ** Do the write.
  474. */
  475. writecode=write(fhandle,buffer,(unsigned)(nbytes & 0xFFFF));
  476. if(writecode==-1)
  477.         *errorcode=ERROR_FILEWRITE;
  478.  
  479. return;
  480. #endif
  481.  
  482. }
  483.  
  484. /********************************
  485. **   ERROR HANDLING ROUTINES   **
  486. ********************************/
  487.  
  488. /****************************
  489. ** ReportError
  490. ** Report error message condition.
  491. */
  492. void ReportError(char *errorcontext,    /* Error context string */
  493.                 int errorcode)          /* Error code number */
  494. {
  495.  
  496. /*
  497. ** Display error context
  498. */
  499. printf("ERROR CONDITION\nContext: %s\n",errorcontext);
  500.  
  501. /*
  502. ** Display code
  503. */
  504. printf("Code: %d",errorcode);
  505.  
  506. return;
  507. }
  508.  
  509. /****************************
  510. ** ErrorExit
  511. ** Peforms an exit from an error condition.
  512. */
  513. void ErrorExit(void)
  514. {
  515.  
  516. /*
  517. ** For profiling on the Mac with MetroWerks -- 11/17/94 RG
  518. ** Have to do this to turn off profiler.
  519. */
  520. #ifdef MACCWPROF
  521. #if __profile__
  522. ProfilerTerm();
  523. #endif
  524. #endif
  525.  
  526. /*
  527. ** FOR NOW...SIMPLE EXIT
  528. */
  529. exit(1);
  530. }
  531.  
  532. /*****************************
  533. **    STOPWATCH ROUTINES    **
  534. *****************************/
  535.  
  536. /****************************
  537. ** StartStopwatch
  538. ** Starts a software stopwatch.  Returns the first value of
  539. ** the stopwatch in ticks.
  540. */
  541. unsigned long StartStopwatch(void)
  542. {
  543. #ifdef MACTIMEMGR
  544. /*
  545. ** For Mac code warrior, use timer. In this case, what we return is really
  546. ** a dummy value.
  547. */
  548. InsTime((QElemPtr)&myTMTask);
  549. PrimeTime((QElemPtr)&myTMTask,-MacHSTdelay);
  550. return((unsigned long)1);
  551. #else
  552. #ifdef WIN31TIMER
  553. /*
  554. ** Win 3.x timer returns a DWORD, which we coax into a long.
  555. */
  556. _Call16(lpfn,"p",&win31tinfo);
  557. return((unsigned long)win31tinfo.dwmsSinceStart);
  558. #else
  559. return((unsigned long)clock());
  560. #endif
  561. #endif
  562. }
  563.  
  564. /****************************
  565. ** StopStopwatch
  566. ** Stops the software stopwatch.  Expects as an input argument
  567. ** the stopwatch start time.
  568. */
  569. unsigned long StopStopwatch(unsigned long startticks)
  570. {
  571.     
  572. #ifdef MACTIMEMGR
  573. /*
  574. ** For Mac code warrior...ignore startticks.  Return val. in microseconds
  575. */
  576. RmvTime((QElemPtr)&myTMTask);
  577. return((unsigned long)(MacHSTdelay+myTMTask.tmCount-MacHSTohead));
  578. #else
  579. #ifdef WIN31TIMER
  580. _Call16(lpfn,"p",&win31tinfo);
  581. return((unsigned long)win31tinfo.dwmsSinceStart-startticks);
  582. #else
  583. return((unsigned long)clock()-startticks);
  584. #endif
  585. #endif
  586. }
  587.  
  588. /****************************
  589. ** TicksToSecs
  590. ** Converts ticks to seconds.  Converts ticks to integer
  591. ** seconds, discarding any fractional amount.
  592. */
  593. unsigned long TicksToSecs(unsigned long tickamount)
  594. {
  595. #ifdef CLOCKWCT
  596. return((unsigned long)(tickamount/CLK_TCK));
  597. #endif
  598.  
  599. #ifdef MACTIMEMGR
  600. /* +++ MAC time manager version (using timer in microseconds) +++ */
  601. return((unsigned long)(tickamount/1000000));
  602. #endif
  603.  
  604. #ifdef CLOCKWCPS
  605. /* Everybody else */
  606. return((unsigned long)(tickamount/CLOCKS_PER_SEC));
  607. #endif
  608.  
  609. #ifdef WIN31TIMER
  610. /* Each tick is 840 nanoseconds */
  611. return((unsigned long)(tickamount/1000L));
  612. #endif
  613.  
  614. }
  615.  
  616. /****************************
  617. ** TicksToFracSecs
  618. ** Converts ticks to fractional seconds.  In other words,
  619. ** this returns the exact conversion from ticks to
  620. ** seconds.
  621. */
  622. double TicksToFracSecs(unsigned long tickamount)
  623. {
  624. #ifdef CLOCKWCT
  625. return((double)tickamount/(double)CLK_TCK);
  626. #endif
  627.  
  628. #ifdef MACTIMEMGR
  629. /* +++ MAC time manager version +++ */
  630. return((double)tickamount/(double)1000000);
  631. #endif
  632.  
  633. #ifdef CLOCKWCPS
  634. /* Everybody else */
  635. return((double)tickamount/(double)CLOCKS_PER_SEC);
  636. #endif
  637.  
  638. #ifdef WIN31TIMER
  639. /* Using 840 nanosecond ticks */
  640. return((double)tickamount/(double)1000);
  641. #endif
  642. }
  643.  
  644.